# coding=utf-8
import json
import os
import smtplib
import sys

import email_util

host = os.getenv('JIANMU_HOST')
port = os.getenv('JIANMU_PORT')
sender = os.getenv('JIANMU_SENDER')
auth_code = os.getenv('JIANMU_AUTH_CODE')
receivers_str = os.getenv('JIANMU_RECEIVERS')
msg_type = os.getenv('JIANMU_TYPE')
subject = os.getenv('JIANMU_SUBJECT')
text = os.getenv('JIANMU_TEXT')
attach_path = os.getenv('JIANMU_ATTACH_PATH')
cc_receivers_str = os.getenv('JIANMU_CC_RECEIVERS')
bcc_receivers_str = os.getenv('JIANMU_BCC_RECEIVERS')
separate_delivery = os.getenv('JIANMU_SEPARATE_DELIVERY')

# 校验输入参数
try:
    receivers = json.loads(receivers_str)
    cc_receivers = json.loads(cc_receivers_str)
    bcc_receivers = json.loads(bcc_receivers_str)
except Exception as e:
    print('error: 收件人、抄送人或密送人格式错误，格式为：\'["aaa@qq.com", "bbb@163.com"]\'')
    sys.exit(1)
if subject.isspace():
    print('error: subject不能为空')
if not text or text.isspace():
    print('error: text不能为空')
msg_types = ['plain', 'html']
if msg_type not in msg_types:
    print('error: type类型定义错误，请输入 plain/html')
    sys.exit(1)
separate_delivery = True if separate_delivery == 'true' else False
if attach_path and not attach_path.isspace():
    if attach_path.endswith('/'):
        attach_path = attach_path[:-1]
    if not os.path.exists(attach_path):
        print('error: 附件不存在，请检查attach_path')
        sys.exit(1)

# 日志
print('发件人：', sender)
if len(receivers) != 0:
    print('收件人：', ', '.join(receivers))
if len(cc_receivers) != 0:
    print('抄送人：', ', '.join(cc_receivers))
if len(bcc_receivers) != 0:
    print('密送人：', ', '.join(bcc_receivers))
print('标题：', subject)
if attach_path and not attach_path.isspace():
    file_name = os.path.basename(attach_path)
    print('文件名：', file_name if os.path.isfile(attach_path) else file_name + '.zip')
print()
print()


def connection():
    try:
        if port == '465':
            server = smtplib.SMTP_SSL(host, port)
        else:
            server = smtplib.SMTP(host, port)
        server.login(sender, auth_code)
        return server
    except Exception as e:
        print('error: 登陆失败！', e)
        sys.exit(1)


def send():
    if separate_delivery:
        print('开始分别发送邮件：')
        all_receivers = set()
        all_receivers.update(receivers)
        all_receivers.update(cc_receivers)
        all_receivers.update(bcc_receivers)
        for receiver in all_receivers:
            single_send(receiver)
    else:
        print('开始发送邮件：')
        batch_send()


def single_send(receiver):
    try:
        server = connection()
        if not attach_path or attach_path.isspace():
            message = email_util.text(sender, [receiver], [], subject, text, msg_type)
        else:
            message = email_util.enclosure(sender, [receiver], [], subject, text, msg_type, attach_path)
        server.sendmail(sender, [receiver], message.as_string())
        server.quit()
        print('success: 已发送到', receiver, '的邮箱中！')
    except Exception as e:
        print('error: 发送邮件到', receiver, '失败！', e)


def batch_send():
    server = connection()
    all_receivers = set()
    all_receivers.update(receivers)
    all_receivers.update(cc_receivers)
    if len(all_receivers) == 0:
        return
    if not attach_path or attach_path.isspace():
        message = email_util.text(sender, receivers, cc_receivers, subject, text, msg_type)
    else:
        message = email_util.enclosure(sender, receivers, cc_receivers, subject, text, msg_type, attach_path)
    try:
        res = server.sendmail(sender, all_receivers, message.as_string())
        server.quit()
    except Exception as e:
        res = {receiver: e for receiver in all_receivers}

    failed_receivers = set(res.keys())
    success_receivers = all_receivers - failed_receivers
    # 打印日志
    batch_send_log(success_receivers, failed_receivers, res)
    cc_send(success_receivers, failed_receivers, res)
    bcc_send(success_receivers, failed_receivers, res)


def batch_send_log(success_receivers, failed_receivers, res):
    if len(receivers) == 0:
        return
    for receiver in receivers:
        # 判断发送成功或失败
        if receiver in success_receivers:
            print('success: 已发送到', receiver, '的邮箱中！')
            continue
        elif receiver in failed_receivers:
            print('error: 发送邮件到', receiver, '失败！', res.get(receiver))
            continue


def cc_send(success_receivers, failed_receivers, res):
    if len(cc_receivers) == 0:
        return
    print()
    print()
    print('开始抄送邮件:')
    for receiver in cc_receivers:
        # 判断发送成功或失败
        if receiver in success_receivers:
            print('success: 已发送到', receiver, '的邮箱中！')
            continue
        elif receiver in failed_receivers:
            print('error: 发送邮件到', receiver, '失败！', res.get(receiver))
            continue


def bcc_send(success_receivers, failed_receivers, res):
    if len(bcc_receivers) == 0:
        return
    print()
    print()
    print('开始密送邮件:')
    for receiver in bcc_receivers:
        # 判断发送成功或失败
        if receiver in success_receivers:
            print('success: 已发送到', receiver, '的邮箱中！')
            continue
        elif receiver in failed_receivers:
            print('error: 发送邮件到', receiver, '失败！', res.get(receiver))
            continue
        try:
            server = connection()
            if not attach_path or attach_path.isspace():
                message = email_util.text(sender, receivers, cc_receivers, subject, text, msg_type)
            else:
                message = email_util.enclosure(sender, receivers, cc_receivers, subject, text, msg_type, attach_path)
            server.sendmail(sender, [receiver], message.as_string())
            server.quit()
            print('success: 已发送到', receiver, '的邮箱中！')
        except Exception as e:
            print('error: 发送邮件到', receiver, '失败！', e)


send()
